//////////////////////////////////////////ok
#include"stdafx.h"

#include "bochs.h"


/* Get CPU version information. */
Bit32u IA32_CPU::get_cpu_version_information()
{
	Bit32u family = 0, model = 0, stepping = 0;
	Bit32u extended_model = 0;
	Bit32u extended_family = 0;
	// Pentium Pro/Pentium II/Pentium III processor
	family   = 6;
	model    = 8;
	stepping = 3;
	return (extended_family << 20) | (extended_model << 16) | (family << 8) |  (model<<4) | stepping;
}       

/* Get CPU extended feature flags. */
Bit32u IA32_CPU::get_extended_cpuid_features()
{
  return 0;
}

/* Get CPU feature flags. Returned by CPUID functions 1 and 80000001.  */
Bit32u IA32_CPU::get_std_cpuid_features()
{
  Bit32u features = 0;
  features |= 0x01;
  features |= (1<< 8);  // Support CMPXCHG8B instruction
  features |= (1<< 4);  // implement TSC
  features |= (1<< 5);  // support RDMSR/WRMSR
  features |= (1<<23);  // support MMX
  features |= (1<<24);  // Implement FSAVE/FXRSTOR instructions.
  features |= (1<<15);  // Implement CMOV instructions.
  features |= (1<<25);  // support SSE
  features |= (1<< 3);  // Support Page-Size Extension (4M pages)
  features |= (1<<13);  // Support Global pages.
  features |= (1<< 6);  // Support PAE.
  return features;
}

void IA32_CPU::CPUID(Ia32_Instruction_c *i)
{
	switch (EAX) 
	{
		case 0:
			// EAX: highest input value understood by CPUID
			EAX = 1;		// for Pentium Pro, Pentium II, Pentium 4 processors
					// should be 2, still not implemented
			// EBX: vendor ID string
			// EDX: vendor ID string
			// ECX: vendor ID string

			EBX = 0x756e6547; // "Genu"
			EDX = 0x49656e69; // "ineI"
			ECX = 0x6c65746e; // "ntel"
			break;
		case 1:
			// EAX:       CPU Version Information
			//   [3:0]   Stepping ID
			//   [7:4]   Model: starts at 1
			//   [11:8]  Family: 4=486, 5=Pentium, 6=PPro, ...
			//   [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
			//   [31:14] Reserved
			// EBX:      
			//   [7:0]   Brand ID
			//   [15:8]  CFLUSH cache line size (value*8 = cache line size in bytes)
			//   [23:16] Number of logical processors in one physical processor
			//   [31:24] Local Apic ID
			// ECX:       Feature Flags::Extended
			//   [0:0]   PNI
			//   [2:1]   Reserved
			//   [3:3]   MONITOR/MWAIT
			//   [4:4]   CPL qualified debug store available
			//   [6:5]   Reserved
			//   [7:7]   Enchanced Intel Speedstep Technology
			//   [8:8]   TM2: Thermal Monitor 2
			//   [12:9]  Reserved
			//   [13:13] CMPXCHG16B
			//   [31:14] Reserved
			// EDX:       Feature Flags
			//   [0:0]   FPU on chip
			//   [1:1]   VME: Virtual-8086 Mode enhancements
			//   [2:2]   DE: Debug Extensions (I/O breakpoints)
			//   [3:3]   PSE: Page Size Extensions
			//   [4:4]   TSC: Time Stamp Counter
			//   [5:5]   MSR: RDMSR and WRMSR support
			//   [6:6]   PAE: Physical Address Extensions
			//   [7:7]   MCE: Machine Check Exception
			//   [8:8]   CXS: CMPXCHG8B instruction
			//   [9:9]   APIC: APIC on Chip
			//   [10:10] Reserved
			//   [11:11] SYSENTER/SYSEXIT support
			//   [12:12] MTRR: Memory Type Range Reg
			//   [13:13] PGE/PTE Global Bit
			//   [14:14] MCA: Machine Check Architecture
			//   [15:15] CMOV: Cond Mov/Cmp Instructions
			//   [16:16] PAT: Page Attribute Table
			//   [17:17] PSE: Page-Size Extensions
			//   [18:18] Processor Serial Number
			//   [19:19] CLFLUSH: CLFLUSH Instruction support
			//   [20:20] Reserved
			//   [21:21] DS: Debug Store
			//   [22:22] ACPI: Thermal Monitor and Software Controlled Clock Facilities
			//   [23:23] MMX Technology
			//   [24]    FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
			//   [25]    SSE: SSE Extensions
			//   [26]    SSE2: SSE2 Extensions
			//   [27]    Reserved
			//   [28]    Hyper Threading Technology
			//   [29]    TM: Thermal Monitor
			//   [31:30] Reserved
			EAX = get_cpu_version_information();
			EBX = 0;
			ECX = get_extended_cpuid_features ();
			EDX = get_std_cpuid_features ();
			break;
		default:
			EAX = 0;
			EBX = 0;
			ECX = 0;
			EDX = 0; // Reserved, undefined
			break;
		}
}
